/////////////////////////////////////////////////////////////////////////////
// Name:        axsampleapp.cpp
// Purpose:     
// Author:      Julian Smart
// Modified by: 
// Created:     20/03/2009 15:46:38
// RCS-ID:      
// Copyright:   
// Licence:     New BSD License
/////////////////////////////////////////////////////////////////////////////

#include "wx/wx.h"
#include "wx/stdpaths.h"
#include "wx/config.h"

////@begin includes
////@end includes

#include "axsampleapp.h"
#include "ax/ax_utils.h"
#include "ax/ax_help_provider.h"

////@begin XPM images
////@end XPM images

/*
 * Application instance implementation
 */

////@begin implement app
IMPLEMENT_APP( AxSampleApp )
////@end implement app


/*
 * AxSampleApp type definition
 */

IMPLEMENT_CLASS( AxSampleApp, wxApp )


/*
 * AxSampleApp event table definition
 */

BEGIN_EVENT_TABLE( AxSampleApp, wxApp )

////@begin AxSampleApp event table entries
////@end AxSampleApp event table entries

END_EVENT_TABLE()


/*
 * Constructor for AxSampleApp
 */

AxSampleApp::AxSampleApp()
{
    Init();
}


/*
 * Member initialisation
 */

void AxSampleApp::Init()
{
    m_frameRect = wxRect(wxDefaultPosition, wxSize(800, 500));
    m_frameStatus = SHOW_STATUS_NORMAL;

    GetViewManager().GetVisualSettings().SetTextSize(12);

////@begin AxSampleApp member initialisation
////@end AxSampleApp member initialisation
}

/*
 * Initialisation for AxSampleApp
 */

bool AxSampleApp::OnInit()
{    
#if wxUSE_XPM
	wxImage::AddHandler(new wxXPMHandler);
#endif
#if wxUSE_LIBPNG
	wxImage::AddHandler(new wxPNGHandler);
#endif
#if wxUSE_LIBJPEG
	wxImage::AddHandler(new wxJPEGHandler);
#endif
#if wxUSE_GIF
	wxImage::AddHandler(new wxGIFHandler);
#endif
    wxHelpProvider::Set(new AxHelpProvider(& GetViewManager().GetSpeech()));

	SampleMainFrame* mainWindow = new SampleMainFrame( NULL, wxID_ANY,
        SYMBOL_SAMPLEMAINFRAME_TITLE, m_frameRect.GetPosition(), m_frameRect.GetSize());

    switch (m_frameStatus)
    {
    case SHOW_STATUS_MAXIMIZED:
        {
            mainWindow->Maximize(true);
            break;
        }
    case SHOW_STATUS_MINIMIZED:
        {
            mainWindow->Iconize(true);
            break;
        }
    default:
    case SHOW_STATUS_NORMAL:
        {
            break;
        }
    }

    // Make sure layout happens while window is hidden
	mainWindow->Layout();
	mainWindow->Show(true);
    mainWindow->Update();

    // By default, enable speech, but only after the UI has been
    // set up (above).
    GetViewManager().GetSpeech().GetPolicy().EnableSpeech();

    InitShortcuts();
    LoadSettings();
    LoadPronunciations();

    GetViewManager().GetSpeech().ClearSpeechEvents();

    GetViewManager().GetSpeech().Say(_("Welcome to the Eh Ex Tee Kay resource sample!"),
                                     AxSpeechFlagsInviolate); // This shouldn't be interrupted by other speech events.
    
    GetViewManager().GetMenuController()->EmitSpeech(AxSpeechEventInitialView);

    GetLibrary().Initialize();
    GetLibrary().SetCommandManager(& m_commandManager);

    wxString appDataDir = AxFileUtilities::GetUserAppDataDirectory(GetAppName());
    wxString libraryDataFile = AxFileUtilities::AppendPaths(appDataDir, wxT("library.dat"));
    wxString mainLibraryPath = AxFileUtilities::AppendPaths(AxFileUtilities::GetDocumentDirectory(), wxT("AxLibrary"));
    if (!wxDirExists(mainLibraryPath))
        wxMkdir(mainLibraryPath);

    GetLibrary().GetSettings().SetLibraryDataFile(libraryDataFile);
    GetLibrary().GetSettings().SetMainLibraryPath(mainLibraryPath);

    GetLibrary().GetSettings().GetSupportedFiles().AddFileType(wxT("epub"),       _("Epub files"));
    GetLibrary().GetSettings().GetSupportedFiles().AddFileType(wxT("mobi"),       _("MobiPocket files"));
    GetLibrary().GetSettings().GetSupportedFiles().AddFileType(wxT("prc"),        _("MobiPocket files"));
    GetLibrary().GetSettings().GetSupportedFiles().AddFileType(wxT("pdf"),        _("PDF files"));
    GetLibrary().GetSettings().GetSupportedFiles().AddFileType(wxT("lit"),        _("Microsoft Reader files"));
    GetLibrary().GetSettings().GetSupportedFiles().AddFileType(wxT("txt"),        _("Text files"));
    GetLibrary().GetSettings().GetSupportedFiles().AddFileType(wxT("mp3"),        _("MP3 audio files"));
    GetLibrary().GetSettings().GetSupportedFiles().AddFileType(wxT("wma"),        _("WMA audio files"));
    GetLibrary().GetSettings().GetSupportedFiles().AddFileType(wxT("ogg"),        _("OGG audio files"));
    GetLibrary().GetSettings().GetSupportedFiles().AddFileType(wxT("spx"),        _("SPX audio files"));

    GetLibrary().LoadLibrary();

    InitializeCommands();

    return true;
}

/*
 * Cleanup for AxSampleApp
 */

int AxSampleApp::OnExit()
{    
    SaveSettings();

    // Get the application data directory for the current user
    wxString appDataDir = AxFileUtilities::GetUserAppDataDirectory(GetAppName());

    /// Save user-specified commands
    wxString cmdManagerFilename = appDataDir + wxFILE_SEP_PATH + wxT("commands.dat");
    
    GetCommandManager().Save(cmdManagerFilename);
    GetCommandManager().Clear();

    GetViewManager().Clear();

    GetLibrary().SaveLibrary();
    
    GetLibrary().Clear();
    GetLibrary().Uninitialize();

////@begin AxSampleApp cleanup
	return wxApp::OnExit();
////@end AxSampleApp cleanup
}

// Load and initialize commands
// Call this after laoding, in case some of them are new and aren't in the file
void AxSampleApp::InitializeCommands()
{
    m_commandManager.SetMenuIdRange(ID_FILE_MENU_START, ID_FILE_MENU_END);

    // Get the application data directory for the current user
    wxString appDataDir = AxFileUtilities::GetUserAppDataDirectory(GetAppName());

    // Load user-specified commands
    wxString cmdManagerFilename = appDataDir + wxFILE_SEP_PATH + wxT("commands.dat");

    if (wxFileExists(cmdManagerFilename))
        m_commandManager.Load(cmdManagerFilename);

    if (!m_commandManager.GetFileType(wxTRANSLATE("HTML files")))
    {
        wxEditorCommands cmds(wxTRANSLATE("HTML files"), wxT(""), wxT("html;htm;xhtml"), wxEditorCommandMediaTypeEbook);
        cmds.InitializeDefaults(wxT("html") /* default for viewing */, wxT("txt") /* default editing */ );
        m_commandManager.AddFileType(cmds);
    }

    if (!m_commandManager.GetFileType(wxTRANSLATE("Text files")))
    {
        wxEditorCommands cmds(wxTRANSLATE("Text files"), wxT(""), wxT("txt"), wxEditorCommandMediaTypeEbook);
        cmds.InitializeDefaults(wxT("txt") /* default for viewing */, wxT("txt") /* default editing */ );
        m_commandManager.AddFileType(cmds);
    }

    if (!m_commandManager.GetFileType(wxTRANSLATE("Image files")))
    {
        wxEditorCommands cmds(wxTRANSLATE("Image files"), wxT(""), wxT("jpg;jpeg;png;bmp;gif;tif;tiff"), wxEditorCommandMediaTypeImage);
        cmds.InitializeDefaults(wxT("png") /* default for viewing */, wxT("png") /* default editing */ );
        m_commandManager.AddFileType(cmds);
    }

    if (!m_commandManager.GetFileType(wxTRANSLATE("CSS files")))
    {
        wxEditorCommands cmds(wxTRANSLATE("CSS files"), wxT(""), wxT("css"), wxEditorCommandMediaTypeDocument);
        cmds.InitializeDefaults(wxT("txt") /* default for viewing */, wxT("txt") /* default editing */ );
        m_commandManager.AddFileType(cmds);
    }
    
    if (!m_commandManager.GetFileType(wxTRANSLATE("Epub files")))
    {
        wxEditorCommands cmds(wxTRANSLATE("Epub files"), wxT(""), wxT("epub"), wxEditorCommandMediaTypeEbook);
        cmds.InitializeDefaults(wxT("epub") /* default for viewing */, wxT("epub") /* default editing */ );
        m_commandManager.AddFileType(cmds);
    }

    if (!m_commandManager.GetFileType(wxTRANSLATE("MobiPocket files")))
    {
        wxEditorCommands cmds(wxTRANSLATE("MobiPocket files"), wxT(""), wxT("mobi;prc"), wxEditorCommandMediaTypeEbook);
        cmds.InitializeDefaults(wxT("mobi") /* default for viewing */, wxT("mobi") /* default editing */ );
        m_commandManager.AddFileType(cmds);
    }

    if (!m_commandManager.GetFileType(wxTRANSLATE("MP3 files")))
    {
        wxEditorCommands cmds(wxTRANSLATE("MP3 files"), wxT(""), wxT("mp3"), wxEditorCommandMediaTypeAudio);
        cmds.InitializeDefaults(wxT("mp3") /* default for viewing */, wxT("mp3") /* default editing */ );

#if shUSE_MEDIACTRL
        if (cmds.FindViewerCommand(wxEDITOR_COMMAND_DEFAULT_NAME))
            cmds.FindViewerCommand(wxEDITOR_COMMAND_DEFAULT_NAME)->Enable(false);
        if (cmds.FindViewerCommand(wxEDITOR_COMMAND_INTERNAL_NAME))
            cmds.FindViewerCommand(wxEDITOR_COMMAND_INTERNAL_NAME)->Enable(true);
#endif

        m_commandManager.AddFileType(cmds);
    }

    if (!m_commandManager.GetFileType(wxTRANSLATE("WMV files")))
    {
        wxEditorCommands cmds(wxTRANSLATE("WMV files"), wxT(""), wxT("wmv"), wxEditorCommandMediaTypeAudio);
        cmds.InitializeDefaults(wxT("wmv") /* default for viewing */, wxT("wmv") /* default editing */ );

#if shUSE_MEDIACTRL
        if (cmds.FindViewerCommand(wxEDITOR_COMMAND_DEFAULT_NAME))
            cmds.FindViewerCommand(wxEDITOR_COMMAND_DEFAULT_NAME)->Enable(false);
        if (cmds.FindViewerCommand(wxEDITOR_COMMAND_INTERNAL_NAME))
            cmds.FindViewerCommand(wxEDITOR_COMMAND_INTERNAL_NAME)->Enable(true);
#endif

        m_commandManager.AddFileType(cmds);
    }
}

// Override this to implement default file launching
bool AxEditorCommandManager::DefaultLaunchFile(const wxString& filename)
{
    return AxFileUtilities::ExecuteFile(filename);
}

void AxSampleApp::LoadPronunciations()
{
    wxStandardPaths paths;
    wxString dataDir = paths.GetUserDataDir();
    if (!wxDirExists(dataDir))
        wxMkdir(dataDir);

    wxString pronunciationTableFilename = wxTextToSpeech::AppendPaths(dataDir, wxT("pronunciation.txt"));

    if (wxFileExists(pronunciationTableFilename))
    {
        GetViewManager().GetSpeech().GetTransformer()->LoadFile(pronunciationTableFilename);
        GetViewManager().GetSpeech().GetTransformer()->Index();
    }    
}

void AxSampleApp::SavePronunciations()
{
    wxStandardPaths paths;
    wxString dataDir = paths.GetUserDataDir();
    wxASSERT(!dataDir.IsEmpty());

    if (!wxDirExists(dataDir))
        wxMkdir(dataDir);

    wxString pronunciationTableFilename = wxTextToSpeech::AppendPaths(dataDir, wxT("pronunciation.txt"));
    GetViewManager().GetSpeech().GetTransformer()->SaveFile(pronunciationTableFilename);
}

// Load settings
bool AxSampleApp::LoadSettings()
{
    wxConfig config(wxT("AxTk Resource Sample"), _T("Anthemion Software"));

    GetViewManager().GetSpeech().LoadSpeechSettings(config);
    GetViewManager().GetVisualSettings().Load(config);
    GetShortcutManager().Load(config);

    config.Read(wxT("WindowSize/X"), & m_frameRect.x);
    config.Read(wxT("WindowSize/Y"), & m_frameRect.y);
    config.Read(wxT("WindowSize/Width"), & m_frameRect.width);
    config.Read(wxT("WindowSize/Height"), & m_frameRect.height);
    config.Read(wxT("WindowSize/Status"), & m_frameStatus);

#if 0
    config.Read(wxT("MP3/UseMP3Encoding"), & m_mp3SettingsInfo.m_enabled);
    config.Read(wxT("MP3/LamePath"), & m_mp3SettingsInfo.m_encoderPath);
    config.Read(wxT("MP3/BitRate"), & m_mp3SettingsInfo.m_bitRate);
#endif
    return true;
}

// Save settings
bool AxSampleApp::SaveSettings()
{
    wxConfig config(wxT("AxTk Resource Sample"), _T("Anthemion Software"));

    GetViewManager().GetSpeech().SaveSpeechSettings(config);
    GetViewManager().GetVisualSettings().Save(config);
    GetShortcutManager().Save(config);

    config.Write(wxT("WindowSize/X"), m_frameRect.x);
    config.Write(wxT("WindowSize/Y"), m_frameRect.y);
    config.Write(wxT("WindowSize/Width"), m_frameRect.width);
    config.Write(wxT("WindowSize/Height"), m_frameRect.height);
    config.Write(wxT("WindowSize/Status"), m_frameStatus);

#if 0
    config.Write(wxT("MP3/UseMP3Encoding"), m_mp3SettingsInfo.m_enabled);
    config.Write(wxT("MP3/LamePath"), m_mp3SettingsInfo.m_encoderPath);
    config.Write(wxT("MP3/BitRate"), m_mp3SettingsInfo.m_bitRate);
#endif

    return true;
}

/// Initialise custom shortcuts
bool AxSampleApp::InitShortcuts()
{
    // Note that we use wxTRANSLATE for the names, since this must be unique whatever the
    // current language setting is. wxTRANSLATE indicates to tools such as poEdit that the
    // string should be translated, but this macro doesn't actually do the translation.
    // Instead, wxGetTranslation is used later when displaying the name in the menu.

#if 0
    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierContextHelp), wxTRANSLATE("Context help"), _("General Shortcuts"), _("Shows help on the focused window, if available"), 0, (int) WXK_F1));
#endif
    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierGoUp), wxTRANSLATE("Go up"), _("General Shortcuts"), _("Goes up to the previous menu"), wxACCEL_CTRL, (int) 'U'));
    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierGoHome), wxTRANSLATE("Go home"), _("General Shortcuts"), _("Goes to the home menu"), wxACCEL_CTRL, (int) 'H'));
    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierStopSpeech), wxTRANSLATE("Stop speaking"), _("General Shortcuts"), _("Stops speaking"), wxACCEL_CTRL, (int) 'G'));
    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierPauseResumeSpeech), wxTRANSLATE("Pause or resume speech"), _("General Shortcuts"), _("Pauses or resumes speech"), wxACCEL_CTRL, (int) 'K'));
#if 0
    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierSkipForward), wxTRANSLATE("Skip forward"), _("General Shortcuts"), _("Skips speech forward"), wxACCEL_ALT|wxACCEL_CTRL, WXK_RIGHT));
    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierSkipBack), wxTRANSLATE("Skip back"), _("General Shortcuts"), _("Skips speech back"), wxACCEL_ALT|wxACCEL_CTRL, WXK_LEFT));
#endif
    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierDescribeContext), wxTRANSLATE("Describe context"), _("General Shortcuts"), _("Describes the current control or menu"), 0, (int) WXK_F2));
    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierDescribeContainerWindow), wxTRANSLATE("Describe window"), _("General Shortcuts"), _("Describes the current window and its children"), wxACCEL_SHIFT, (int) WXK_F2));
    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierDescribeItem), wxTRANSLATE("Describe item"), _("General Shortcuts"), _("Describes the current menu item"), wxACCEL_CTRL|wxACCEL_ALT, (int) 'I'));

    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierReadCurrentWord), wxTRANSLATE("Read current word"),
        _("Text Shortcuts"), _("Reads the current word in a text control."),
        wxACCEL_CTRL, (int) '1'));

    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierReadPreviousWord), wxTRANSLATE("Read previous word"),
        _("Text Shortcuts"), _("Reads the previous word in a text control."),
        wxACCEL_CTRL, (int) WXK_LEFT));

    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierReadNextWord), wxTRANSLATE("Read next word"),
        _("Text Shortcuts"), _("Reads the next word in a text control."),
        wxACCEL_CTRL, (int) WXK_RIGHT));

    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierReadCurrentSentence), wxTRANSLATE("Read current sentence"),
        _("Text Shortcuts"), _("Reads the current sentence in a text control."),
        wxACCEL_CTRL, (int) '2'));

    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierReadPreviousSentence), wxTRANSLATE("Read previous sentence"),
        _("Text Shortcuts"), _("Reads the previous sentence in a text control."),
        wxACCEL_CTRL|wxACCEL_SHIFT, (int) WXK_LEFT));

    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierReadNextSentence), wxTRANSLATE("Read next sentence"),
        _("Text Shortcuts"), _("Reads the next sentence in a text control."),
        wxACCEL_CTRL|wxACCEL_SHIFT, (int) WXK_RIGHT));

    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierReadCurrentParagraph), wxTRANSLATE("Read current paragraph"),
        _("Text Shortcuts"), _("Reads the current paragraph in a text control."),
        wxACCEL_CTRL, (int) '3'));

    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierReadPreviousParagraph), wxTRANSLATE("Read previous paragraph"),
        _("Text Shortcuts"), _("Reads the previous paragraph in a text control."),
        wxACCEL_CTRL, (int) WXK_UP));

    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierReadNextParagraph), wxTRANSLATE("Read next paragraph"),
        _("Text Shortcuts"), _("Reads the next paragraph in a text control."),
        wxACCEL_CTRL, (int) WXK_DOWN));

    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierReadFromHere), wxTRANSLATE("Read from here"),
        _("Text Shortcuts"), _("Reads the text from the current position in the text control."),
        wxACCEL_ALT, (int) WXK_END));

    GetShortcutManager().Add(
        wxShortcutItem(AxGetId(AxIdentifierReadAll), wxTRANSLATE("Read all"),
        _("Text Shortcuts"), _("Reads all the text in the text control."),
        wxACCEL_ALT|wxACCEL_CTRL, (int) WXK_HOME));

    return true;
}
